package com.moonLight.weblog.admin.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.moonLight.weblog.admin.model.vo.category.AddCategoryReqVO;
import com.moonLight.weblog.admin.model.vo.category.DeleteCategoryReqVO;
import com.moonLight.weblog.admin.model.vo.category.FindCategoryPageListReqVO;
import com.moonLight.weblog.admin.model.vo.category.FindCategoryPageListRspVO;
import com.moonLight.weblog.admin.service.AdminCategoryService;
import com.moonLight.weblog.common.domain.dos.CategoryDO;
import com.moonLight.weblog.common.domain.dos.TArticleCategoryRelDo;
import com.moonLight.weblog.common.domain.mapper.CategoryMapper;
import com.moonLight.weblog.common.domain.mapper.TArticleCategoryMapper;
import com.moonLight.weblog.common.enums.ResponseCodeEnum;
import com.moonLight.weblog.common.exception.BizException;
import com.moonLight.weblog.common.model.vo.SelectRspVO;
import com.moonLight.weblog.common.utils.PageResponse;
import com.moonLight.weblog.common.utils.Response;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
public class AdminCategoryServiceImpl  implements AdminCategoryService {
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private TArticleCategoryMapper tArticleCategoryMapper;


    @Override
    public Response addCategory(AddCategoryReqVO addCategoryReqVO) {
        //拿到参数
        String name = addCategoryReqVO.getName();
        //判断数据库是否存在
        if (categoryMapper.selectByName(name) == null) {
            //不存在，添加 构建categoryDo
            CategoryDO categoryDO = CategoryDO.builder().name(name).build();
            //执行sql
            categoryMapper.insert(categoryDO);
            return Response.success();
        }else{
            log.warn("分类名称: {},此分类已经存在", name);
            //抛出 业务异常通知
            throw new BizException(ResponseCodeEnum.CATEGORY_NAME_IS_EXISTED);

        }
    }

    @Override
    public PageResponse findCategoryPageList(FindCategoryPageListReqVO findCategoryPageListReqVO) {
        // 获取当前页、以及每页需要展示的数据数量
        Long current = findCategoryPageListReqVO.getCurrent();
        Long size = findCategoryPageListReqVO.getSize();

        // 分页对象(查询第几页、每页多少数据)
        // 和数据库操作就需要使用和数据库对应的Do实体类CategoryDO
        Page<CategoryDO> page = new Page<>(current, size);

        // 构建查询条件
        LambdaQueryWrapper<CategoryDO> wrapper = new LambdaQueryWrapper<>();

        String name = findCategoryPageListReqVO.getName();
        LocalDate startDate = findCategoryPageListReqVO.getStartDate();
        LocalDate endDate = findCategoryPageListReqVO.getEndDate();


        //  name.trim() 去除空格
        // 条件 类的属性名 数值
        wrapper
                .like(StringUtils.isNotBlank(name), CategoryDO::getName, name) // like 模块查询
                .ge(Objects.nonNull(startDate), CategoryDO::getCreateTime, startDate) // 大于等于 startDate
                .le(Objects.nonNull(endDate), CategoryDO::getCreateTime, endDate)  // 小于等于 endDate
                .orderByDesc(CategoryDO::getCreateTime); // 按创建时间倒叙

        // 执行分页查询
        Page<CategoryDO> categoryDOPage = categoryMapper.selectPage(page, wrapper);

        List<CategoryDO> categoryDOS = categoryDOPage.getRecords();

        // DO 转 VO 数据脱敏
        List<FindCategoryPageListRspVO> vos = null;
        if (!CollectionUtils.isEmpty(categoryDOS)) {
            vos = categoryDOS.stream()
                    .map(categoryDO -> FindCategoryPageListRspVO.builder()
                            .id(categoryDO.getId())
                            .name(categoryDO.getName())
                            .createTime(categoryDO.getCreateTime())
                            .articlesTotal(categoryDO.getArticlesTotal())
                            .build())
                    .collect(Collectors.toList());
        }

        return PageResponse.success(categoryDOPage, vos);

    }

    /**
     * 当该分类存在文章的时候不能删除
     * 1. 先根据分类iD 在关联表中查询是否存在文章 Limit 1 提升性能
     * 2. 存在 返回失败
     * 3. 不存在 删除
     * @param deleteCategoryReqVO
     * @return
     */
    @Override
    public Response deleteCategory(DeleteCategoryReqVO deleteCategoryReqVO) {
        //结合实际业务场景来分析，其实没有必要做逻辑删除，直接物理删除就好了。
        // 分类 ID
        Long categoryId = deleteCategoryReqVO.getId();


        TArticleCategoryRelDo tArticleCategoryRelDo = tArticleCategoryMapper.selectOneByCategoryId(categoryId);

        if (Objects.nonNull(tArticleCategoryRelDo)){
            log.warn("==> 此分类下包含文章，无法删除，categoryId: {}", categoryId);
            throw new BizException(ResponseCodeEnum.CATEGORY_CAN_NOT_DELETE);
        }
        // 删除分类
        categoryMapper.deleteById(categoryId);

        return Response.success();

    }

    @Override
    public Response findCategorySelectList() {
        List<CategoryDO> categoryDOS = categoryMapper.selectList(null);

        List<SelectRspVO> collect = null;
        //Do 转 Vo
        if (!CollectionUtils.isEmpty(categoryDOS)) {
            collect = categoryDOS.stream().map(categoryDO -> SelectRspVO.builder()
                            .label(categoryDO.getName())
                            .value(categoryDO.getId())
                            .build())
                    .collect(Collectors.toList());
        }

        return Response.success(collect);
    }
}
